RA -*- mode: org; -*-

help: [C-uc .] insert timestamp [C-cc] flip checkbox [C-uucc] partial flip [M-RET] continue list
checkbox [C-ct] flip TODO

#+STARTUP: logdone

* TODO [1/7]
  - [-] Bugs [5/16]
    - [ ] Fix reduction-1.cc: "real_part(iter<1>(m)) = real_part(iter<1>(c))"
    - [ ] Invalid expressions that aren't caught by Match, either bc it makes assumptions, or bc
      Match isn't even involved. See checks.cc.
    - [X] Before merging saveload [1/1]
      - [X] Fix cellrank.cc: "using View::operator= on sliding view". For that, View::operator= have
        to be const. That breaks a lot of things
        - Fixed by duplicating operator= overloads on Container :-\ <2023-11-17 Fri 16:33>
    - [ ] const issues in View vs Container
      - [ ] conversion to const & op in ViewBig uses reinterpret_const
    - [X] ra::Small<real, 3, 3, 3>() benchmark in bench-dot.cc has op 10x worse
      than indexed
      - Fixed in ca20c1678bb7aa43ccf6b4fe1b93ee9c742b1630. Yay!
      - Appears to have regressed in 65076211eeeeecd8623877e3e3b5cc0a87af302c, although by a smaller factor. Bummer.
      - Looks good in v20 in g++-11, but bad in 12/13. Bummer.
      - Investigated & resolved in e297ee0561a647065fb5b92880fe0f994340595c ss.
    - [ ] Small/Big unification
    - [ ] Forbid initialization from higher rank
      - Cf 'Initialization of nested types' in the manual.
    - [X] size_s, rank_s in Ryn:: are broken [ra7]
    - [X] broken with -DNDEBUG (95ac2014bfd86cbc27e3d151f55abaceef628de4 and by <2023-05-26 Fri 15:08> in CI)
    - [ ] ambiguity / bad init in nested constructors [ra45]
    - [ ] ra::at(A, I) needs nested I, so the obvious ra::at(A, [i j]) doesn't work (although
      view.at([i j]) does). But I would get rid of view.at(i) if ra::at(view, i) worked the same
      way.
    - [ ] subscripting inconsistencies; for example, if `A` is rank>1 and `i` is rank 1, then `A(i)`
      will return a nested expression instead of preserving `A`'s rank [ra33]
    - [ ] beatable subscripts are not beaten if mixed with non-beatable subscripts. E.g. in
      A(vector, iota, vector) the iota isn't beaten. [ra33].
    - [ ] be namespace clean except for possibly the scalar block in ra.hh. Document exactly what is exported to ::.
    - [ ] bad uses of assert [ra17]
    - [X] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90745 (bad operator=) is cleared up. Cf [ra5].
  - [-] Features [3/17]
    - [-] support std::format
      - [X] basic support
      - [X] ways to use the formatter without parsing, like ra::format_t { .option = value ... }.
      - [ ] ellipsis feature, e.g. max width/max length.
      - [ ] formatting options for the shape (needed?)
    - [ ] compatibility with OpenMP, even if only for trivially parallel cases
          The way ply() works atm, with iterators, more or press precludes it.
    - [ ] support expr = braces for any expr, not just views.
    - [ ] make iter work with w/rank.
    - [ ] make iter work with foreign vectors.
    - [ ] Can choose iteration order in plyers. Order is already explicit, just need to expose it.
    - [X] Merge Ptr and Iota. Why need more than one rank 1 Iterator adaptor.
    - [-] Deduction guides, e.g. ra::Small a = {{1, 2}, {3, 4}} ?! maybe rank 1 first
      - [X] rank 1 SmallArray <2023-06-23 Fri 13:24> (not very useful)
      - [ ] rank >1 SmallArray
      - [ ] Small
      - [ ] Big
    - [ ] Support ra::len in x in o.len(x).
    - [ ] Shape returns Small not std::array (for static rank expr).
    - [X] Should be able to reshape iota (??). One idea is to generalize View (so View<iota>, etc.)
      which is something that newra does. But as long as Container is parent of View, conversion of
      (Container const &) into (View const &) forces us to have const/nonconst overloads in View
      (instead of just relying on the constness of (View::p). This is just a mess when View::p isn't
      a pointer.
      - [X] Fix relationship between Container and View [4/4]
        - [X] fwd const/nonconst overloads to View or ViewConst from here.
        - [X] add const/nonconst casts of Container to View or ViewConst
        - [X] remove const overloads from View::operator()
        - [X] make View be View<pointer> and not View<value_type>
    - [ ] Remove inheritance relationship of Container on ViewBig
    - [ ] Should be able to turn ravel iterators (e.g. ViewBig::begin()) into array iterators. Ptr()
      doesn't work for that.
      - This has become more feasible after changing the iterator interface from flat to saveload,
        main obstacle atm seems to be the need to support copy. <2023-11-20 Mon 12:45>
      - One can now create a ravel iterator from an Iterator <2023-11-28 Tue 16:37>
    - [ ] gemv(conj(a), b) should work. Beat View-like selectors down a Map??
    - [ ] port some of the View ops to generic Iterator. reverse, transpose, etc. seem easy
      enough. Only it kind of bothers me that they need their own Map-like types while on Views
      it's just a one time op. Propagating ops down Map into leaf Views (a kind of beating) would
      be better.
    - [X] Support operator <=> <2020-09-15 Tue 13:50>
      - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96278 is annoying
    - [-] Magic subscript len
      - [X] For Big/View in beatable subscripts <2023-07-04 Tue 18:20>
      - [X] For Big/View in unbeatable subscripts <2023-07-05 Wed 12:34>
      - [X] For Small/ViewSmall
        - [X] Scalar / unbeatable <2023-08-04 Fri 14:18>
        - [X] iota. But iota args need to integral constants for this to work.
      - [ ] Optimize iota(len...) + iota(len...)
  - [-] Performance [2/4]
    - [ ] bench/bench-stencil* is weird.
    - [ ] Bigd cases in bench-at.
    - [X] `*(it.flat())` is inefficient for some it, eg CellBig, because we need to create/copy flat
      in case it gets modified, and then it isn't. Do we need Iterator::operator* ?
    - [X] During traversal (ply) the pattern loc = save_location(it); move flat;
      it.set_location(loc); would allow flat to modify the original it. Loc is often just a pointer
      so this would be cheap. The current design is that move flat can't modify it so it has to be a
      new object. CellBig is one case where that is costly, because dimv has to be copied along with
      the pointer to make up a View, even though dimv is constant all through traversal.
  - [X] Error report, debugging [3/3]
    - [X] Optionally throw instead of abort on bounds checks, etc. cf. test/ra-12.cc
      * This was fixed between v8 and v10, see examples/throw.cc.
    - [X] Static check on Small constructors e.g. real3 {1, 2, 3}. Cf big.hh:513 init<SS>(SS const & s).
      - [X] for Container constructors
      - [X] for Small constructors
    - [X] General static check on prefix matching <2019-02-06 Wed 12:06>
  - [-] Building, tests [4/6]
    - [X] Build docs with cmake
    - [X] Support RA_USE_BLAS with cmake (linux)
    - [X] Support RA_USE_BLAS with cmake (mac) <2018-12-07 Fri 16:33>
    - [X] TestRecorder.test_eq with mismatched shapes aborts. Should just fail the test. <2023-07-10 Mon 13:14>
      - We have had agree() for a while.
    - [ ] Make cmake tests respect dependences and able to be run independently.
    - [ ] Test for expected compilation errors (static_assert, etc) [ra42].
      - One idea (libc++?) is to fork() and check that child breaks.
  - [ ] Documentation [0/3]
    - [ ] Complete section on internals
    - [ ] Complete section on other languages, libraries
    - [ ] Describe xreferenced issues in doc ([raxx], etc.)
  - [ ] Other [0/4]
    - [ ] Reconsider len/len_s etc: Same as there are static/nonstatic versions of keep, we
      could remove len_s/rank_s use staticness of len/rank instead of ANY/ANY. A problem with this
      is that len_s lets me return ANY for some axes and finite for others and to do that with just
      len() would require len(integral constant) overloads possibly -- len(int k) cannot be static
      or not depending on k.
    - [ ] Review Container constructors. Why do we need (&) when we have (const &)?
    - [ ] Support tuple as a kind of foreign vector
      - [ ] Iterator type for tuple (like Vector for std::vector).
      - [ ] Appropriate ply. Possibly restrict it to rank 1.
    - [ ] Current & future C++
      - [ ] static_assert(__cpp_constexpr >= 202306L);  // c++26
      - [ ] static_assert(__cpp_static_assert >= 202306L); // c++26


Some of these aren't bugs in the sense that I expect to solve them, but more like footnotes.

* Numbered issues throughout the source [ra...]
  1. [ ]
  2. [ ]
  3. [ ]
  4. [ ] test/optimize.cc: Expression objects only keep pointers to data objects. This means that it
     is unsafe to define expression objects unless none of the data objects are
     temporaries. E.g. `auto e = temp + temp;` is unsafe. Either `obj a; obj b; auto e = a + b;` or
     `obj o = temp + temp;` is safe. Generally there's no reason to ever define expression objects
     explicitly.
  5. [ ]
  6. [ ]
  7. [ ]
  8. [X] test/operators.cc: Some simple expressions with scalars fail in VALUE(). The patch in ra.hh
     triggers the address sanitizer in test/ra-9.cc.
  9. [ ] test/ra-6.cc: ra::Ptr doesn't hold copies. This enables restarting (see [ra39]), so
     ra::ptr(temp) must only be used as temp. Really forbidding auto ll = ra::ptr(lvalue) would also
     be ok.
  10. [ ] test/ra-0.cc: size(SmallArray) requires ra:: to avoid collision with std::size, but not
      size(Big) (??).
  11. [ ]
  12. [ ]
  13. [ ] ra/ply.hh (i/o), ra/expr.hh, ra/base.hh, test/compatibility.cc: std::string used to
      be registered as scalar, but that clashes with how std::ranges sees it. OTOH we don't want
      format(std::string_view) to print it as a foreign vector, so we have an exception for it
      there. As things stand, you can register it as scalar or not.
  14. [ ] CellBig needs to copy its Dimv in some cases, which also complicates ViewBig::iter<>. Problem
      is demonstrated in ra-5.cc.
  15. [ ] Conversion-to-scalar operators for dynamic-rank ViewBig(). I thought this could be
      https://wg21.link/cwg976 but gcc 14 doesn't fix it. There are two issues here, 1) why isn't
      const conversion enough and 2) ambiguity with Small's 'any' constructor (cf 'c++ converting
      constructor vs conversion operator').
  16. [ ] Ambiguity in ravel vs nested constructors bc bc 1 converts to int2. Should be explicit
      (and ravel constructors also).
  17. [ ] assert() is used in some cases for runtime conditions that aren't ra::'s fault. This is
      bad because if RA_ASSERT is defined to throw, the caller probably expects to be able to handle
      the error. On the other hand if RA_DO_CHECK is 0, we shouldn't continue. But ofc we do in
      index checks etc. So is this different?
  18. [ ]
  19. [ ]
  20. [ ]
  21. [ ]
  22. [ ]
  23. [ ]
  24. [ ]
  25. [ ]
  26. [ ]
  27. [ ]
  28. [ ]
  29. [ ]
  30. [ ]
  31. [ ]
  32. [ ]
  33. [ ] test/frame-old.cc, test/fromb.cc: When mixing beaten & unbeaten subscripts and the
      unbeaten subscripts go first, the result is a nested expression. This has to be fixed in the
      view operator()s.
  34. [ ]
  35. [ ]
  36. [ ]
  37. [ ]
  38. [ ]
  39. [ ] test/ra-7.cc: There's no reason to restart, since the Iterator methods are all static. So
      start(ra::Scalar) just fwds. But that means that Scalar::c maintain constness, so a const
      overload is required for ScalarFlat::operator*.
  40. [ ]
  41. [ ]
  42. [ ] Ways to test that compile time assertions or constraints are triggered appropriately,
      esp. for things like ct array lookup.  Some are doable with concepts, see e.g. ra-14.cc or
      big-0.cc.
  43. [ ]
  44. [ ]
  45. [ ]
  46. [ ]
  47. [ ] ra/big.hh, test/const.cc, ra/view-ops.hh ...: Review constness in ra/view-ops.hh after the
      Big/ViewBig const fixes after 913d6b531801609cb61bb7f631ddf50de701a802.
